package com.gite.nouette.admin.implementation.model;

import java.util.ArrayList;
import java.util.List;

import com.gite.nouette.admin.contract.model.IContainerModule;
import com.gite.nouette.admin.contract.model.IModule;
import com.gite.nouette.admin.contract.model.IPair;

public class ContainerModuleImpl extends AbstractModel implements
		IContainerModule {
	private List<List<IModule>> modules;

	public ContainerModuleImpl() {
		setModules(new ArrayList<List<IModule>>());
	}

	public List<List<IModule>> getModules() {
		return this.modules;
	}

	public void setModules(List<List<IModule>> modules) {
		this.modules = modules;
	}

	@Override
	public List<IModule> removeColumn(int index) {
		return getModules().remove(index);
	}

	@Override
	public void addColumn(int index) {
		getModules().add(index, new ArrayList<IModule>());
	}

	@Override
	public IPair<Integer, Integer> addModule(IModule module) {
		IPair<Integer, Integer> added = new PairImpl<Integer, Integer>();
		added.setX(getNextIndexColumn());
		added.setY(addModule(module, added.getX()));

		return added;
	}

	@Override
	public int addModule(IModule module, int colNum) {
		List<IModule> column = getColumn(colNum);
		return addModule(module, column);
	}

	@Override
	public void addModule(IModule module, int colNum, int rowNum) {
		List<IModule> column = getColumn(colNum);
		addModule(module, column, rowNum);
	}

	private int addModule(IModule module, List<IModule> column) {
		column.add(module);
		return column.indexOf(module);
	}

	private void addModule(IModule module, List<IModule> column, int rowNum) {
		column.add(rowNum, module);
	}

	@Override
	public boolean removeModule(IModule module) {
		List<IModule> column = getColumnOfModule(module);
		if (column != null) {
			return column.remove(module);
		}
		return false;
	}

	@Override
	public int getNbModule() {
		int nbModule = 0;
		for (List<IModule> column : getModules()) {
			nbModule += getNbModuleByColumn(column);
		}
		return nbModule;
	}

	@Override
	public int getNbColumn() {
		return getModules().size();
	}

	@Override
	public int getNextIndexColumn() {
		return getModules().indexOf(getNextColumn());
	}

	private List<IModule> getNextColumn() {
		List<IModule> nextColumn = null;
		for (List<IModule> column : getModules()) {
			if (nextColumn == null || nextColumn.size() > column.size()) {
				nextColumn = column;
			}
		}
		return nextColumn;
	}

	private List<IModule> getColumn(int index) {
		try {
			return getModules().get(index);
		} catch (IndexOutOfBoundsException e) {
		}
		return null;
	}

	private List<IModule> getColumnOfModule(IModule module) {
		for (List<IModule> column : getModules()) {
			if (column.contains(module)) {
				return column;
			}
		}
		return null;
	}

	private int getNbModuleByColumn(List<IModule> column) {
		return column.size();
	}

	public int getNbModuleByColumn(int indexColumn) {
		return getNbModuleByColumn(getColumn(indexColumn));
	}

	public void moveModule(IModule module, int indexColumn, int indexRow) {
		List<IModule> column = getColumnOfModule(module);
		column.remove(module);
		List<IModule> columnTarget = getColumn(indexColumn);
		columnTarget.add(indexRow, module);
	}
}
